home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / blix / blixscore_io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.6 KB  |  324 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*__________________________________________________________________
  18.  |
  19.  | blixscore_io.c - part of blixscore.c
  20.  |
  21.  | these routines are not in blixscore.c, because they are used
  22.  | by the blixserver program too.
  23.  |
  24.  | (c) 1994 Frans van Hoesel, hoesel@chem.rug.nl
  25.  |               Xtreme Graphics Software
  26.  |
  27. */
  28.  
  29. #include <unistd.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <fcntl.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <errno.h>
  37. #include <limits.h>
  38. #include <dirent.h>
  39.  
  40. #include "blixscore_io.h"
  41.  
  42. int sginap(long ticks);
  43.  
  44. /*__________________________________________________________________
  45.  |
  46.  | write_data - write a data block
  47.  | 
  48.  | a block of data is written, preceeded with is length
  49.  | when length is negative, only the data is written.
  50.  |
  51. */
  52.  
  53. int write_data(int f, void *lbuf, int len) {
  54.     
  55.     int result;
  56.     int leng;
  57.     char *buf;
  58.     
  59.     buf = (char *)lbuf;
  60.     
  61.     if (len >= 0) {
  62.     if (write(f, &len, 4) != 4)
  63.     return -1;
  64.     } else {
  65.     len = -len;
  66.     }
  67.     leng = len;
  68.     while (len > 0) {
  69.     if (len > 512) {
  70.         result = write(f, buf, 512);
  71.     } else {
  72.         result = write(f, buf, len);
  73.     }
  74.     len -=result;
  75.     buf += result;
  76.     if (result <= 0)
  77.         return -1;
  78.     }
  79.     return leng;
  80. }
  81.  
  82. /*__________________________________________________________________
  83.  |
  84.  | read_data - read a data block
  85.  | 
  86.  | first the length of the block is read, then the data block with that
  87.  | length. a negative value of maxlength implies a read, without the
  88.  | preceeding length being read, but instead reads exactly -maxlen bytes
  89. */
  90.  
  91. int read_data(int f, void *lbuf, int maxlen) {
  92.     
  93.     int len, leng;
  94.     int result;
  95.     char *buf;
  96.     
  97.     buf = (char *)lbuf;
  98.     if (maxlen >= 0) {
  99.     leng = 4;
  100.     while (leng > 0) {
  101.         result = read(f, buf, leng);
  102.         if (result <= 0 ) {
  103.         return -1; 
  104.         }
  105.         leng -= result;
  106.         buf += result;
  107.     }
  108.     len = *((int *)lbuf);
  109.     buf = (char *)lbuf;
  110.     if (len > maxlen) {            /* protocol error */
  111.         fprintf(stderr, "protocol error: got length %d "
  112.             "expected at most %d\n", len, maxlen);
  113.         return -1;
  114.     }
  115.     } else {
  116.     len = -maxlen;
  117.     }
  118.     if (len > 100000) {
  119.     /* obviously no image is this large, or it would be rejected
  120.      * anyway (max size is 100 x 100)
  121.      */
  122.      return -1;
  123.     }
  124.     leng = len;
  125.     while (len > 0) {
  126.     if (len > 512) {
  127.         result = read(f, buf, 512);
  128.     } else {
  129.         result = read(f, buf, len);
  130.     }
  131.     if (result <= 0) {
  132.         return -1;
  133.     }
  134.     len -= result;
  135.     buf += result;
  136.     }
  137.     return leng;
  138. }
  139.  
  140.  
  141. /*__________________________________________________________________
  142.  |
  143.  | readstr - read a string
  144.  |
  145.  | read a string; limit the length of the string to 127, so you
  146.  | can read the result in an array of know size; and appends a
  147.  | '\0' at the end of the string;
  148.  |
  149. */
  150.  
  151. int readstr(int f, char *s) {
  152.     int len;
  153.     len = read_data(f, s, 127);
  154.     if (len >= 0) {
  155.     *(s+len) = '\0';
  156.     } else {
  157.     /* create an empty string */
  158.     *s = '\0';
  159.     }
  160.     return len;
  161. }
  162.  
  163.  
  164. /*__________________________________________________________________
  165.  |
  166.  | writestr - write a string
  167.  |
  168. */
  169.  
  170. int writestr(int f, char *s) {
  171.     if (s == NULL )
  172.     return (write_data(f, "", strlen("")));
  173.     else 
  174.     return (write_data(f, s, strlen(s)));
  175. }
  176.  
  177.  
  178. /*__________________________________________________________________
  179.  |
  180.  | openscore - open the file with score
  181.  |
  182.  | this opens and locks the file that contains the high scores.
  183.  | file locking is done so more than one game may be running at
  184.  | any time. This is particulary true for the server side of
  185.  | the world wide highscores, but may also effect your system
  186.  | high score list.
  187.  | the timeout value is a float number and gives the timeout
  188.  | in seconds.
  189.  | If the file does not exists,it is created, but left empty.
  190.  |
  191. */
  192.  
  193. int openscore(const char *path, float timeout) {
  194.     int f;
  195.     int retry;
  196.     
  197.     errno = 0;
  198.     f = open(path, O_RDWR | O_CREAT, 0666);
  199.     /* my guess is that the next test will always fail (f is always 
  200.      * set, but just in case)
  201.     */
  202.     retry = 0;
  203.     if (f == -1 && (errno == EAGAIN || errno == EACCES)) {
  204.     while (f == -1 && (errno == EAGAIN || errno == EACCES) &&
  205.         retry < timeout * 10) {
  206.         sginap(CLK_TCK/10);
  207.         retry++;
  208.         f = open(path, O_RDWR | O_CREAT, 0666);
  209.     }
  210.     }
  211.     if (f != -1) {
  212.     /* lock the file */
  213.     retry = 0;
  214.     while (lockf(f, F_TLOCK, 0) != 0 && retry < timeout &&
  215.         (errno == EAGAIN || errno == EACCES )) {
  216.         retry++;
  217.         errno = 0;
  218.         sginap(CLK_TCK/10);
  219.     }
  220.     if (retry >= timeout || errno == EAGAIN || errno == EACCES) {
  221.         close(f);
  222.         f = -1;
  223.     }
  224.     }
  225.     return f;
  226. }
  227.  
  228. /*__________________________________________________________________
  229.  | 
  230.  | readscore - read the score list
  231.  |
  232.  | if the list does not exists, a default one is created.
  233.  |
  234. */
  235.  
  236. int readscore(int f, scorelist_t *scorelist) {
  237.     
  238.     char tmpstr[128];
  239.     int i;
  240.     
  241.     tmpstr[0] = '\0';
  242.     if (f == -1 || readstr(f,tmpstr) <= 0 || strncmp(tmpstr, "BLIX", 4)) {
  243.     scorelist->game = 0;
  244.     scorelist->id = 1;
  245.     for (i=0; i<7; i++) {
  246.         strcpy(scorelist->names[i], "Blix");
  247.         strcpy(scorelist->hosts[i], "Xtreme Graphics Software");
  248.         scorelist->images[i][0]  = '\0';
  249.         scorelist->scores[i] = 2000 - i * 250;
  250.         scorelist->addrs[i] = 0;
  251.     }
  252.    } else {
  253.     read_data(f, &(scorelist->game), sizeof(long));
  254.     read_data(f, &(scorelist->id), sizeof(long));
  255.     for (i=0; i<7; i++) {
  256.         readstr(f, tmpstr);
  257.         strcpy(scorelist->names[i], tmpstr);
  258.         readstr(f, tmpstr); 
  259.         strcpy(scorelist->hosts[i], tmpstr);
  260.         readstr(f, tmpstr);
  261.         strcpy(scorelist->images[i], tmpstr);
  262.         read_data(f, &(scorelist->scores[i]), sizeof(long));
  263.         read_data(f, &(scorelist->addrs[i]), sizeof(long));
  264.     }
  265.     }
  266.     return 0;
  267. }
  268.  
  269. /*__________________________________________________________________
  270.  | 
  271.  | writescore - write the score list
  272.  |
  273. */
  274.  
  275. void writescore(int f, scorelist_t *scorelist) {
  276.     int i;
  277.     
  278.     if (f == -1)
  279.     return;
  280.     writestr(f, "BLIX");
  281.     write_data(f, &(scorelist->game), sizeof(long));
  282.     write_data(f, &(scorelist->id), sizeof(long));
  283.     for (i=0; i< 7; i++) {
  284.     writestr(f, scorelist->names[i]);
  285.     writestr(f, scorelist->hosts[i]);
  286.     writestr(f, scorelist->images[i]);
  287.     write_data(f, &(scorelist->scores[i]), sizeof(long));
  288.     write_data(f, &(scorelist->addrs[i]), sizeof(long));
  289.     }
  290. }
  291.  
  292. void cleanup_images(scorelist_t *scorelist, char *dirnam, char *ext) {
  293.    
  294.     DIR *dirp;
  295.     struct dirent *dp;
  296.     int found;
  297.     int i;
  298.     char tmpstr[512];
  299.     char c;
  300.     
  301.     dirp = opendir(dirnam);
  302.     if (dirp == NULL)
  303.     return;
  304.     while ((dp = readdir(dirp)) != NULL) {
  305.     c = *(dp->d_name);
  306.     if (c >= '0' && c <= '9' && strstr(dp->d_name, ext)) {
  307.         /* see if this image is in the list; if not unlink it */
  308.         found = 0;
  309.         for (i=0; i< 7; i++) {
  310.         if (scorelist->images[i] != NULL && 
  311.             strstr(scorelist->images[i], dp->d_name) != NULL)
  312.             found = 1;    
  313.         }
  314.         if (found == 0) {
  315.         strcpy(tmpstr, dirnam);
  316.         strcat(tmpstr, "/");
  317.         strcat(tmpstr, dp->d_name);
  318.         unlink(tmpstr);
  319.         }
  320.     }
  321.     }
  322.     closedir(dirp);
  323. }
  324.